package com.fr71.project.dm.listener;

import com.fr71.common.utils.DateUtils;
import com.fr71.common.utils.spring.SpringUtils;
import com.fr71.project.dm.domain.PdUser;
import com.fr71.project.dm.service.IPdUserService;
import com.fr71.project.dm.utils.DMUtils;
import com.fr71.project.dm.utils.RedisUtil;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.BotFactory;
import net.mamoe.mirai.contact.*;
import net.mamoe.mirai.event.EventHandler;
import net.mamoe.mirai.event.SimpleListenerHost;
import net.mamoe.mirai.event.events.*;
import net.mamoe.mirai.message.data.*;
import net.mamoe.mirai.utils.BotConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

@Component
public class MiraiComponent {

    private static final Logger logger = LoggerFactory.getLogger(MiraiComponent.class);

    // 机器人QQ
    private static final long BOT_QQ = 3648415L;

    // 主人qq
    private static final long ADMIN = 3648415L;

    // 需要处理的群里列表
    private static final long GROUP = 105681818L;
    private static final long GROUP2 = 222131426L;

    private Bot bot;

    @Autowired
    private IPdUserService mIPdUserService;

    private final GroupLevel[] grouLevels = {
        new GroupLevel(0, "小弟"),
        new GroupLevel(17, "五弟"),
        new GroupLevel(34, "四弟"),
        new GroupLevel(51, "三哥"),
        new GroupLevel(68, "二哥"),
        new GroupLevel(85, "大哥")
    };

    private GroupLevel getLevel(net.mamoe.mirai.contact.active.MemberActive active) {
        int temperature = active.getTemperature();
        GroupLevel level;
        if (temperature >= 0 && temperature <= 16) {
            level = grouLevels[0];
        } else if (temperature >= 17 && temperature <= 33) {
            level = grouLevels[1];
        } else if (temperature >= 34 && temperature <= 50) {
            level = grouLevels[2];
        } else if (temperature >= 51 && temperature <= 67) {
            level = grouLevels[3];
        } else if (temperature >= 68 && temperature <= 100) {
            level = grouLevels[4];
        } else {
            level = grouLevels[0];
        }
        level.setLevel(temperature);
        return level;
    }

    // @PostConstruct
    public void init() {
        try {
            logger.debug("进入mirai初始化");
            
            BotConfiguration config = new BotConfiguration();
            config.setProtocol(BotConfiguration.MiraiProtocol.ANDROID_WATCH);
            
            bot = BotFactory.INSTANCE.newBot(BOT_QQ, "", config);
            bot.login();
            logger.debug("机器人登录完成");
        } catch (Exception e) {
            logger.error("机器人登录失败", e);
        }
    }

    @PreDestroy
    public void destroy() {
        if (bot != null) {
            bot.close();
        }
        logger.debug("机器人已关闭");
    }

    public static class GroupLevel {
        private int level;
        private final String title;

        public GroupLevel(int level, String title) {
            this.level = level;
            this.title = title;
        }

        public int getLevel() {
            return level;
        }

        public void setLevel(int level) {
            this.level = level;
        }

        public String getTitle() {
            return title;
        }
    }

    public static class MiraiListener extends SimpleListenerHost {
        private final Logger logger = LoggerFactory.getLogger(MiraiListener.class);
        private final IPdUserService mIPdUserService;
        private final GroupLevel[] grouLevels = {
            new GroupLevel(0, "小弟"),
            new GroupLevel(17, "五弟"),
            new GroupLevel(34, "四弟"),
            new GroupLevel(51, "三哥"),
            new GroupLevel(68, "二哥"),
            new GroupLevel(85, "大哥")
        };

        public MiraiListener(IPdUserService mIPdUserService) {
            this.mIPdUserService = mIPdUserService;
        }
        
        private GroupLevel getLevel(net.mamoe.mirai.contact.active.MemberActive active) {
            int temperature = active.getTemperature();
            GroupLevel level;
            if (temperature >= 0 && temperature <= 16) {
                level = grouLevels[0];
            } else if (temperature >= 17 && temperature <= 33) {
                level = grouLevels[1];
            } else if (temperature >= 34 && temperature <= 50) {
                level = grouLevels[2];
            } else if (temperature >= 51 && temperature <= 67) {
                level = grouLevels[3];
            } else if (temperature >= 68 && temperature <= 100) {
                level = grouLevels[4];
            } else {
                level = grouLevels[0];
            }
            level.setLevel(temperature);
            return level;
        }

        /**
         * 私聊消息到达回调
         */
        @EventHandler
        public void onMessage(FriendMessageEvent event) {
            logger.debug("机器人收到私聊消息");

            String content = event.getMessage().contentToString();
            if (content.startsWith("激活体验卡")) {
                // 激活体验卡 用key在redis找到这个记录 找不到返回错误
                try {
                    String[] spList = content.split(" ");

                    if (spList.length < 3) {
                        event.getSender().sendMessage("激活失败，参数不完整。");
                        return;
                    }

                    String key = spList[1];
                    String ip = spList[2];

                    // checkIp
                    if (!isValidIpAddress(ip)) {
                        event.getSender().sendMessage("激活失败，IP输入错误。").recallIn(60 * 1000);
                        return;
                    }

                    com.fr71.project.dm.domain.QQTryCodeBean data = RedisUtil.getTryCodeTypeByKey(event.getSender().getId(), key);
                    if (data == null) {
                        event.getSender().sendMessage("激活失败，未查找到标识符。").recallIn(60 * 1000);
                        return;
                    }

                    String sCode = DMUtils.generateUniqueSafCode();
                    PdUser user = new PdUser();
                    user.setUpdateTime(DateUtils.getNowDate());
                    user.setCreateTime(user.getUpdateTime());
                    user.setBindIp(ip);
                    user.setAuthStartTime(DateUtils.getNowDate());
                    user.setAuthEndTime(DateUtils.addHours(new Date(), data.getAddTime()));
                    user.setSCode(sCode);
                    user.setUType(data.getuType());
                    user.setAuthType(0);
                    user.setChangeTimesMonth(1);
                    user.setVersion("v1.0.0");
                    user.setBindQq(String.valueOf(event.getSender().getId()));

                    if (mIPdUserService.insertPdUser(user) > 0) {
                        RedisUtil.delTryCodeTypeMark(event.getSender().getId(), key);
                        event.getSender().sendMessage(
                                "激活成功，体验卡" + sCode + "已绑定到IP:" + ip + "，请使用该IP安装工具会自动激活。\n" +
                                        "教程：https://www.fr71.com/archives/cywd\n密码：666"
                        );
                    } else {
                        event.getSender().sendMessage("激活失败，ip冲突或其他错误。");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("尝试激活体验卡失败，数据结构拆分异常。");
                    event.getSender().sendMessage("激活失败，不支持的结构体。");
                    // 注意：这里需要获取Bot实例才能发送消息给管理员
                }
            }
        }

        /**
         * 群组消息到达回调
         */
        @EventHandler
        public void onMessage(GroupMessageEvent event) {
            logger.debug("机器人收到群聊消息");
            Group group = event.getGroup();
            Member sender = event.getSender();

            if (group.getId() == GROUP) {
                // 判断荣耀等级 达到17的可以领取
                GroupLevel level = getLevel(sender.getActive());

                String messageContent = event.getMessage().contentToString();

                // 大群
                if ("领取体验卡".equals(messageContent)) {
                    // 领取体验卡

                    if (level.getLevel() < 17) {
                        MessageChainBuilder builder = new MessageChainBuilder();
                        builder.append(new At(sender.getId()));
                        builder.append(" 你当前的群荣耀等级为[" + level.getTitle() + "(lv" + level.getLevel() + ")]，暂时无法领取体验卡。可发送消息“福利”来查询领取规则。");
                        MessageChain message = builder.build();
                        group.sendMessage(message);
                        return;
                    } else {
                        // 可以领取的时候查一下这周有没有权限
                        if (!RedisUtil.canGetTryCode(sender.getId())) {
                            MessageChainBuilder builder = new MessageChainBuilder();
                            builder.append(new At(sender.getId()));
                            builder.append(" 你本周的可用次数为0，请在下周来领取吧。");
                            MessageChain message = builder.build();
                            group.sendMessage(message);
                            return;
                        }

                        String oldUUID = RedisUtil.getKeyByqq(sender.getId());
                        if (oldUUID != null) {
                            MessageChainBuilder builder = new MessageChainBuilder();
                            builder.append(new At(sender.getId()));
                            builder.append(" 你领取的体验卡还未激活，请私聊我并发送“激活体验卡 " + oldUUID + " 你的IP”来激活。");
                            MessageChain message = builder.build();
                            group.sendMessage(message);
                            return;
                        }

                        String uuid = "";
                        String title = "";
                        // 可以领取
                        if ("五弟".equals(level.getTitle())) {
                            // 每周可以领取一张12小时体验卡
                            uuid = RedisUtil.insertAnTryCodeMark(sender.getId(), 0, 12);
                            title = "12小时";
                        } else if ("四弟".equals(level.getTitle())) {
                            // 每周可以领取一张1天体验卡
                            uuid = RedisUtil.insertAnTryCodeMark(sender.getId(), 0, 24);
                            title = "1天";
                        } else if ("三哥".equals(level.getTitle())) {
                            // 每周可以领取一张3天体验卡
                            uuid = RedisUtil.insertAnTryCodeMark(sender.getId(), 0, 3 * 24);
                            title = "3天";
                        } else if ("二哥".equals(level.getTitle())) {
                            // 每周可以领取一张5天体验卡
                            uuid = RedisUtil.insertAnTryCodeMark(sender.getId(), 0, 5 * 24);
                            title = "5天";
                        } else if ("大哥".equals(level.getTitle())) {
                            // 每周可以领取一张7天体验卡
                            uuid = RedisUtil.insertAnTryCodeMark(sender.getId(), 0, 7 * 24);
                            title = "7天";
                        }

                        if (uuid != null && !uuid.isEmpty()) {
                            MessageChainBuilder builder = new MessageChainBuilder();
                            builder.append(new At(sender.getId()));
                            builder.append(
                                    " 你已成功领取" + title + "Linux工具箱体验卡，请使用当前QQ私聊我并发送“激活体验卡 " + uuid + " 你的IP”以激活卡密。\n" +
                                            "五分钟内有效，过期将作废。"
                            );
                            MessageChain message = builder.build();
                            group.sendMessage(message);
                        }
                    }
                } else if ("福利".equals(messageContent)) {
                    MessageChainBuilder builder = new MessageChainBuilder();
                    builder.append(new At(sender.getId()));
                    builder.append(
                            " 本群活跃值奖励系统规则如下（以下奖励周/qq可领取一次，每周一00:00重置次数）：\n" +
                                    "五弟(lv17-lv33): Linux工具箱12小时体验卡\n" +
                                    "四弟(lv34-lv50): Linux工具箱体验天卡\n" +
                                    "三哥(lv51-lv67): Linux工具箱体验3天卡\n" +
                                    "二哥(lv51-lv67): Linux工具箱5天卡\n" +
                                    "大哥(lv68-lv100):Linux工具箱周卡\n" +
                                    "你当前的等级为:" + level.getTitle() + "(lv" + level.getLevel() + ")"
                    );
                    MessageChain message = builder.build();
                    group.sendMessage(message);
                }
            } else if (group.getId() == GROUP2) {
                // 处理自动回复
                String result = getSearchResult(event.getMessage().contentToString());
                if (result != null && !result.isEmpty()) {
                    MessageChainBuilder builder = new MessageChainBuilder();
                    builder.append(new At(sender.getId()));
                    builder.append("\n");
                    builder.append(result);
                    MessageChain message = builder.build();
                    group.sendMessage(message);
                }
            }
        }

        public String getSearchResult(String content) {
            String result = "";

            if (content.contains("1024")) {
                result = "1024 游戏服务器响应数据处理异常";
            } else if (content.contains("1025")) {
                result = "1025 玩家在游戏过程被管理员封号掉线";
            } else if (content.contains("1026")) {
                result = "1026 玩家在游戏过程被管理员封设备掉线";
            } else if (content.contains("1027")) {
                result = "1027 插件限制最大允许创建一个角色，该账号可能使用其他登录器创建了多个角色，插件过滤了其他的角色，只保留了等级最高的显示";
            } else if (content.contains("1028")) {
                result = "1028 创建角色错误，无法删除系统创建的默认角色";
            } else if (content.contains("1029")) {
                result = "1029 创建角色错误，无法写入角色基础数据，检查错误日志";
            } else if (content.contains("1030")) {
                result = "1030 创建角色错误，无法写入角色大飞模版数据，检查错误日志。";
            } else if (content.contains("1031")) {
                result = "1031 创建角色错误，无法写入角色空背包数据，检查错误日志。";
            } else if (content.contains("1032")) {
                result = "1032 创建角色错误，无法写入角色patch数据，检查错误日志。";
            } else if (content.contains("1033")) {
                result = "1033 上线赠送道具失败，检查错误日志。";
            } else if (content.contains("1034")) {
                result = "1034 上线赠送首饰失败，检查错误日志。";
            } else if (content.contains("1035")) {
                result = "1035 上线赠送黑水晶失败，检查错误日志。";
            } else if (content.contains("1036")) {
                result = "1036 上线赠送装备失败，检查错误日志。";
            } else if (content.contains("1037")) {
                result = "1037 上线赠送宠物失败，检查错误日志。";
            } else if (content.contains("1038")) {
                result = "1038 上线赠送坐骑失败，检查错误日志。";
            } else if (content.contains("1039")) {
                result = "1039 上线赠送法宝失败，检查错误日志。";
            } else if (content.contains("1040")) {
                result = "1040 后台开启了在线发货，玩家注册角色后写入引路人积分时异常";
            } else if (content.contains("1041")) {
                result = "1041 后台管理页面配置关闭了角色创建";
            } else if (content.contains("1042")) {
                result = "1042 接入插件后最大支持创建一个角色";
            } else if (content.contains("1043")) {
                result = "1043 网关配置关闭了新角色的创建";
            } else if (content.contains("1044")) {
                result = "1044 总后台检测到插件异常，可能为服务器网络中断时间过久或插件授权已到期";
            } else if (content.contains("1045")) {
                result = "1045 插件有新版本且限制强更，更新插件后可恢复正常";
            } else if (content.contains("1046")) {
                result = "1046 该账号被配置为挂机的GM账号，挂机GM号只能同时登陆一个，可在后台踢出GM后重新修改账号或再次登陆";
            } else if (content.contains("1047")) {
                result = "1047 插件设置页面禁止了所有玩家登陆";
            } else if (content.contains("1048")) {
                result = "1048 网关限制了最大可登陆的角色数量，套盾时请关闭网关配置中的登陆数量限制。";
            } else if (content.contains("1049")) {
                result = "1049 插件设置禁止了所有玩家的交易";
            } else if (content.contains("1050")) {
                result = "1050 特殊地图限制中开启了时间的限制导致地图无法进入";
            } else if (content.contains("1051")) {
                result = "1051 玩家尝试从引路人发货商店进货被拦截";
            } else if (content.contains("1052")) {
                result = "1052 GM不在线，无法扣除属性类的消耗";
            } else if (content.contains("1053")) {
                result = "1053 染色系统未开启，无法染色";
            } else if (content.contains("1054")) {
                result = "1054 宠物死绑配置了该宠物无法被丢弃";
            } else if (content.contains("1055")) {
                result = "1055 玩家进入角色选择页面时无法读取到登陆的账号，可能为跨越业务攻击封包";
            } else if (content.contains("1056")) {
                result = "1056 redis缓存引起的同源失败";
            } else if (content.contains("1057")) {
                result = "1057 玩家的属性不足无法扣除,同源失败";
            } else if (content.contains("1058")) {
                result = "1058 GM号不在线，无法扣除属性消耗，同源失败";
            } else if (content.contains("1059")) {
                result = "1059 不支持的同源消耗类型，检查配置";
            } else if (content.contains("1060")) {
                result = "1060 门派转换异常，该角色未读取到技能信息";
            } else if (content.contains("1061")) {
                result = "1061 登陆封包处理异常，断开了链接";
            } else if (content.contains("1062")) {
                result = "1062 插件设置开启了封包校验，检测到该封包时间戳异常，断开链接";
            } else if (content.contains("1063")) {
                result = "1063 插件设置开启了测试线路，最后一条线路仅允许GM进入";
            } else if (content.contains("1064")) {
                result = "1064 CDK兑换属性奖励异常。GM号不在线";
            } else if (content.contains("1065")) {
                result = "1065 发货字典中找不到兑换的道具";
            } else if (content.contains("1066")) {
                result = "1066 CDK兑换元宝异常，检查数据库链接";
            } else if (content.contains("1067")) {
                result = "1067 玩家的GID读取失败，无法判定当前是否已膜拜，需要重新登陆";
            } else if (content.contains("1068")) {
                result = "1068 GM不在线，无法扣除属性奖励完成首饰转换次数重置";
            } else if (content.contains("1069")) {
                result = "1069 CDK使用标记失败，可能为数据库链接延迟了，重试一次";
            } else if (content.contains("1070")) {
                result = "1070 不满足特殊地图要求强制进入地图被踢出";
            } else if (content.contains("1071")) {
                result = "1071 GM号不在线，玩家进入试道场调整本月当行失败";
            } else if (content.contains("1072")) {
                result = "1072 无法获取玩家进入试道场保存的真实道行，重启redis";
            } else if (content.contains("1073")) {
                result = "1073 使用的道具被限制了右键直接使用。插件设置页面配置";
            } else if (content.contains("1074")) {
                result = "1074 Boss消耗道具时异常，道具被绑定或加锁状态";
            } else if (content.contains("1075")) {
                result = "1075 配置的在线发货字典道具已经不存在";
            } else if (content.contains("1076")) {
                result = "安全验证服务被客户端尝试使用封包攻击，已拦截";
            } else if (content.contains("安装命令")) {
                result = "sudo yum install -y wget && wget --no-check-certificate --no-cache --no-cookies -q -O /usr/bin/wd https://oss-12311.oss-cn-beijing.aliyuncs.com/pjsqj/fg && chmod +x /usr/bin/wd | echo '安装成功，请输入wd启动工具箱'";
            } else if (content.contains("区组名称")) {
                result = "区组名称与选择线路时显示的名称无直接关联，线路的名称可以随便写。区组名称与可使用的GM权限有直接关系\n" +
                        "区组名称为问道一区时可以使用300权限\n" +
                        "试剑内侧可使用1000权限\n" +
                        "其他任何区组名均可使用200权限。";
            } else if (content.contains("备份")) {
                result = "在Linux工具箱首页选择2（问道服务管理）、5（备份游戏数据），或6（恢复游戏数据）即可完成游戏数据的备份和恢复，备份的数据库表为：dl_adb_all.account、dl_ddb_1.gid_info、dl_ddb_1.basic_char_info、dl_ddb_1.data、dl_ddb_1.top_data。备份文件为加密压缩文件，只能用于恢复数据，无法自行修改其中的内容。";
            } else if (content.contains("恢复")) {
                result = "在Linux工具箱首页选择2（问道服务管理）、5（备份游戏数据），或6（恢复游戏数据）即可完成游戏数据的备份和恢复，备份的数据库表为：dl_adb_all.account、dl_ddb_1.gid_info、dl_ddb_1.basic_char_info、dl_ddb_1.data、dl_ddb_1.top_data。备份文件为加密压缩文件，只能用于恢复数据，无法自行修改其中的内容。";
            } else if (content.contains("架设失败")) {
                result = "多次架设失败可能是在架设过程中下载安装包时被手动中断或网络异常引起的安装包不完整引起的，可以在Linux工具箱首页选择7（皮蛋多功能工具箱）、5（清理下载缓存）清理缓存后再次尝试。";
            } else if (content.contains("时间")) {
                result = "游戏中显示的时间和当前时间不一致,可能是因为服务器的时区设置不当导致的，可在Linux工具箱首页选择7（皮蛋多功能工具箱）、8（一键同步服务器时间）进行修复，修复没有效果的可以重启服务器同步完时间后再启动游戏服务端。";
            } else if (content.contains("不刷星")) {
                result = "排行榜不刷新或不刷星,游戏限制了排行榜的刷新时间，并不是角色数据产生后立刻刷新。需要等待一段时间后刷新，如果两三天后依然不刷新则可能是服务器时间不对引起的，可参考游戏中显示的时间和当前时间不一致的解决方法。";
            } else if (content.contains("自己关闭")) {
                result = "服务器配置低导致游戏线路自己关闭,如果你是1核2G的配置开了8条线，那就洗洗睡吧。其他正常状态可以试试加虚拟内存，可在Linux工具箱首页选择7（皮蛋多功能工具箱）、15（虚拟内存管理）、1（添加虚拟内存），加的虚拟内存尽量不要超过你的最大物理内存。";
            } else if (content.contains("防火墙")) {
                result = "在Linux工具箱首页选择7（皮蛋多功能工具箱）、1（防火墙管理），开启防火墙时工具会自动放行游戏相关的端口，如果有安装插件时则会自动禁止原始端口进入游戏。关闭防火墙时工具会自动删除以上规则。";
            } else if (content.contains("防御系统")) {
                result = "防御系统是什么,防御系统利用玩家对游戏服务端的链接数进行防御，开启防御系统时会要求属于一个防御的阈值，这个阈值便是一个玩家最大允许链接到游戏服务端的链接数量，例如你的安全验证端口是8101，玩家进入游戏登录界面时则持有了一个游戏服务端的链接，如果你设置的链接数量大于了玩家持有的链接数量时该IP会被拉黑。架设攻击者利用相同IP对安全验证端口进行攻击时，则会在瞬间持有成百上千的链接，开启防御系统后可以有效的进行防御。注意：无法避免多ip的同时暴力攻击，原理参考以上说明。";
            } else if (content.contains("激活码")) {
                result = "激活码绑定服务器，每个激活码每月可以免费换绑一次，在新的服务器安装完工具箱并输入wd后会提示输入激活码，如果输入你在其他服务器使用过的激活码则自动换绑到新的服务器。";
            } else if (content.contains("换绑")) {
                result = "每个月有一次免费换绑次数，如果没有免费换绑次数了还有换绑需求，则需要在赞助页面对激活码完成一次任意金额的续费即可重置换绑次数，续费后换绑次数会被重置为0，本月可再换绑一次。";
            } else if (content.contains("续费")) {
                result = "目前不支持续费操作";
            } else if (content.contains("环境")) {
                result = "插件运行必须的环境是CentOS7.x，redis、Java11、mysql5.7+";
            } else if (content.contains("超时")) {
                result = "首先确认服务器时间是否正常，再确认12346端口是否占用，其他错误可以查阅插件日志定位问题。如果日志目录下没有任何错误信息，则确认内存是否够用，启动插件最少预留1g以上可用内存。在命令框输入以下命令,是否显示跟下图一致，不一致的在首页选择7（皮蛋多功能工具箱），重装java环境。";
            } else if (content.contains("日志")) {
                result = "插件的日志在服务器的/var/log/fg/plugin目录下，err开头的是错误日志，如果有错误会在这个文件里看到。";
            } else if (content.contains("用户名")) {
                result = "默认的用户名为admin，密码为123456，这个用户名永远不会变，密码重装插件后会被重置为123456。";
            } else if (content.contains("密码")) {
                result = "如何重置插件密码，群文件下载重置密码的sql脚本文件，拖入plugin数据库即可重置密码，重置后密码会被恢复为默认值123456。";
            } else if (content.contains("禁止登录")) {
                result = "在插件设置页面，找到登录数量限制，设置为不限制或大于1的数字。";
            } else if (content.contains("cdk注册")) {
                result = "在cdk管理页面生成注册cdk，在网关配置中开启cdk创建角色选项，玩家在创建角色页面会被要求输入cdk验证。";
            } else if (content.contains("GM号")) {
                result = "为什么要挂GM号，由于玩家进入游戏后所有的临时数据都是存在内存中，玩家在退出游戏时才会写入数据库。插件无法直接读取游戏服务内存中的数据，只能借助GM号修改玩家属性的功能做到修改游戏临时数据。如果没有挂GM号，则游戏中所有涉及角色属性的奖励或扣除将失效或异常，例如道行、潜能、游戏币等奖励。另外一个用处是同步游戏的一些基础数据，例如所有的地图以及用到的npc、在线发货使用的引路人商店等。";
            } else if (content.contains("离线")) {
                result = "我的GM号挂了一会就显示离线了。插件后台选择ETC系统，点击修复掉线问题并重新打包重启线路即可。";
            } else if (content.contains("登录器")) {
                result = "怎么生成登录器。插件设置页面，点击生成登录器，选择一个牛逼的样子，点击生成即可开始生成，生成后会自动下载。生成比较耗时并且吃服务器内存，请耐心等待。";
            } else if (content.contains("无法关闭")) {
                result = "插件首页的更新弹窗无法关闭。强制更新的新版本提示无法关闭，并且不更新会无法登录游戏。";
            } else if (content.contains("更新")) {
                result = "插件怎么更新，在Linux工具箱首页选择6（插件管理）、选择3（更新插件）即可完成更新，更新后会自动重启插件，无需手动启动。手动玩家更新时参考安装过程，将plugin,sql更换为update.sql拖入数据库即可，同时替换新的启动器starter与插件包release.jar。";
            } else if (content.contains("在线发货")) {
                result = "在线发货是从引路人商店拿货，保证游戏只能从插件代理端口进入，否则可能被刷。";
            } else if (content.contains("端口")) {
                result = "插件用到了哪些端口。http协议12346端口，前端UI交互；\n" +
                        "tcp协议 60000端口，与登录器通信；\n" +
                        "其他TCP端口，跟游戏aaa与线路端口、线路数量动态计算。\n端口的正常范围：1-65535";
            } else if (content.contains("被刷")) {
                result = "能刷物资肯定有以下安全隐患之一\n" +
                        "\n" +
                        "一些游戏商城，消耗类被修改为0，例如积分大使的商品兑换积分设置为0，七周年商城兑换消耗类周年卡被设置为0，等其他商店类型。\n" +
                        "数据库开了外网访问，被人试到了密码，有了密码什么都可以干。\n" +
                        "电脑中毒，用了带毒的exe，你电脑中键盘、鼠标的任何操作，别人都能看到，所以拿你个密码不是事。\n" +
                        "使用插件的引路人空投功能，道具放在引路人商店导致被刷。\n" +
                        "怎么解决？对应上面提出的问题\n" +
                        "\n" +
                        "消耗类被设置为0肯定是你想把这个商店当成你GM拿货的商店使用，那么就从根源解决问题，发货时玩家离线直接发到背包去，清空商店道具配置，这里有个误区大家要知道，上面提到的商店以及没有提到的金币商店等，都是可以远程购买的，你不管放在哪里，只要里面有道具，他就能通过封包去远程购买。\n" +
                        "关了自己数据库的外网访问权限，或指定你自己的IP为白名单。\n" +
                        "安装杀软，例如火绒。\n" +
                        "关闭原始aaa验证端口，让玩家强制通过插件进入游戏。插件进入游戏的玩家通过任何方式刷引路人商店，都是会被拦截下来。（数据库密码泄露防不了）。有工具箱的安装完插件后在工具箱首页选7（皮蛋多功能工具箱）开启防火墙即可，会自动禁止数据库外网访问与原始aaa验证端口的关闭。";
            }

            return result;
        }

        /**
         * 群临时会话消息
         */
        @EventHandler
        public void onMessage(GroupTempMessageEvent event) {
            String content = event.getMessage().contentToString();
            if (content.startsWith("激活体验卡")) {
                // 激活体验卡 用key在redis找到这个记录 找不到返回错误
                try {
                    String[] spList = content.split(" ");

                    if (spList.length < 3) {
                        event.getSender().sendMessage("激活失败，参数不完整。");
                        return;
                    }

                    String key = spList[1];
                    String ip = spList[2];

                    // checkIp
                    if (!isValidIpAddress(ip)) {
                        event.getSender().sendMessage("激活失败，IP输入错误。").recallIn(60 * 1000);
                        return;
                    }

                    com.fr71.project.dm.domain.QQTryCodeBean data = RedisUtil.getTryCodeTypeByKey(event.getSender().getId(), key);
                    if (data == null) {
                        event.getSender().sendMessage("激活失败，未查找到标识符。").recallIn(60 * 1000);
                        return;
                    }

                    String sCode = DMUtils.generateUniqueSafCode();
                    PdUser user = new PdUser();
                    user.setUpdateTime(DateUtils.getNowDate());
                    user.setCreateTime(user.getUpdateTime());
                    user.setBindIp(ip);
                    user.setAuthStartTime(DateUtils.getNowDate());
                    user.setAuthEndTime(DateUtils.addHours(new Date(), data.getAddTime()));
                    user.setSCode(sCode);
                    user.setUType(data.getuType());
                    user.setAuthType(0);
                    user.setChangeTimesMonth(1);
                    user.setVersion("v1.0.0");
                    user.setBindQq(String.valueOf(event.getSender().getId()));

                    if (mIPdUserService.insertPdUser(user) > 0) {
                        RedisUtil.delTryCodeTypeMark(event.getSender().getId(), key);
                        event.getSender().sendMessage(
                                "激活成功，体验卡" + sCode + "已绑定到IP:" + ip + "，请使用该IP安装工具会自动激活。\n" +
                                        "教程：https://www.fr71.com/archives/cywd\n密码：666"
                        );
                    } else {
                        event.getSender().sendMessage("激活失败，ip冲突或其他错误。");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("尝试激活体验卡失败，数据结构拆分异常。");
                    event.getSender().sendMessage("激活失败，不支持的结构体。");
                }
            }
        }

        /**
         * 陌生人消息
         */
        @EventHandler
        public void onMessage(StrangerMessageEvent event) {
            // 空实现，可以按需添加处理逻辑
        }

        /**
         * 验证IP地址格式是否正确
         * @param ip IP地址字符串
         * @return 如果是有效的IP地址返回true，否则返回false
         */
        private boolean isValidIpAddress(String ip) {
            return ip.contains(".");
        }

        /**
         * 机器人登陆的回调
         */
        @EventHandler
        public void onLogin(BotOnlineEvent event) {
            logger.debug("机器人登陆完成");
            // sendMsgToAdmin(event.getBot(), "机器人登陆成功");

            Group g = event.getBot().getGroup(GROUP2);
            if (g != null) {
                StringBuilder delNices = new StringBuilder();
                
                for (NormalMember member : g.getMembers()) {
                    if (!(member.getPermission() == MemberPermission.ADMINISTRATOR || member.getPermission() == MemberPermission.OWNER)) {
                        long qq = member.getId();
                        logger.debug("{} - {}", member.getNameCard(), member.getId());
                        
                        PdUser queryUser = new PdUser();
                        queryUser.setBindQq(String.valueOf(qq));
                        List<PdUser> list = mIPdUserService.selectPdUserList(queryUser);

                        if (list == null || list.isEmpty()) {
                            delNices.append(member.getNameCard()).append("(").append(member.getId()).append(") - 未找到qq绑定的工具箱或插件\n");
                            member.sendMessage(member.getNameCard() + "(" + member.getId() + ")，未在用户列表中查询到与当前QQ绑定的数据，已将您移除" + g.getName() + "(" + g.getId() + ")，请将软件绑定QQ后使用绑定的QQ重新入群。");
                            try {
                                // member.kick("用户列表中查询到与当前QQ绑定的数据", false);
                            } catch (Exception e) {
                                logger.error("踢出用户失败", e);
                            }
                        } else {
                            boolean allOld = true;
                            for (PdUser user : list) {
                                if (user.getUpdateTime() != null && user.getUpdateTime().after(DateUtils.addDays(new Date(), -15))) {
                                    allOld = false;
                                    break;
                                }
                            }
                            
                            if (allOld) {
                                member.sendMessage(member.getNameCard() + "(" + member.getId() + ")，系统查询到与该QQ绑定的软件长时间未使用，已将您移除" + g.getName() + "(" + g.getId() + ")，请自行留存相关激活码，在使用时再次申请入群。激活码丢失不补。");
                                delNices.append(member.getNameCard()).append("(").append(member.getId()).append(") - 工具箱与插件长时间未使用\n");
                                try {
                                    // member.kick("系统查询到与该QQ绑定的软件长时间未使用", false);
                                } catch (Exception e) {
                                    logger.error("踢出用户失败", e);
                                }
                            }

                            boolean allExpired = true;
                            for (PdUser user : list) {
                                if (user.getAuthEndTime().after(DateUtils.getNowDate())) {
                                    allExpired = false;
                                    break;
                                }
                            }
                            
                            if (allExpired) {
                                logger.debug("{}({})，系统查询到与该QQ绑定的软件已全部到期，已将您移除{}({})。", 
                                        member.getNameCard(), member.getId(), g.getName(), g.getId());
                                try {
                                    // member.kick(member.getNameCard() + "(" + member.getId() + ")，系统查询到与该QQ绑定的软件已全部到期，已将您移除" + g.getName() + "(" + g.getId() + ")。", false);
                                } catch (Exception e) {
                                    logger.error("踢出用户失败", e);
                                }
                            }
                        }
                    }
                }

                if (delNices.length() > 0) {
                    g.sendMessage("以下用户已被移除本群。\n" + delNices.toString());
                    logger.debug(delNices.toString());
                }
            }
        }

        /**
         * 机器人下线的回调
         */
        @EventHandler
        public void onLogin(BotOfflineEvent event) {
            logger.error("机器人已下线");
        }
    }
}